﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace DivaScript
{
    /// <summary>
    /// Project DIVA PV Command.
    /// </summary>
    public class PvCommand
    {
        private string opcode;

        /// <summary>
        /// Command identifier.
        /// </summary>
        public string Opcode
        {
            get => opcode;
            set => opcode = value;
        }

        /// <summary>
        /// Generic command used for sorting.
        /// </summary>
        internal Command GenericCommand
        {
            get
            {
                Command command = Command.UNKNOWN_COMMAND;

                Enum.TryParse(Opcode, out command);

                return command;
            }
        }

        /// <summary>
        /// Command timestamp.
        /// </summary>
        public int TimeStamp { get; set; }

        /// <summary>
        /// Command timespan
        /// </summary>
        public TimeSpan TimeSpan
        {
            get => TimeSpan.FromMilliseconds(TimeStamp / 100.0);
        }

        /// <summary>
        /// Integer command paramter list.
        /// </summary>
        public List<int> Parameters { get; set; }

        public PvCommand(int timeStamp, string opcode, List<int> param)
        {
            Opcode = opcode;
            TimeStamp = timeStamp;
            Parameters = param;
        }

        public PvCommand(int timeStamp, string opcode, params int[] param)
        {
            Opcode = opcode;
            TimeStamp = timeStamp;
            Parameters = param.ToList();
        }

        /// <summary>
        /// Returns a string equivalent for this command.
        /// </summary>
        public override string ToString()
        {
            string str = $"{Opcode}(";
            for (int i = 0; i < Parameters.Count; i++)
            {
                str += string.Format("{0}{1}", Parameters[i], (i < Parameters.Count - 1) ? ", " : "");
            }
            str += ");";
            return str.ToUpper();
        }
    }

    /// <summary>
    /// Generic PV command used for sorting.
    /// </summary>
    internal enum Command : int
    {
        TIME, MIKU_MOVE, MIKU_ROT, MIKU_DISP, MIKU_SHADOW, SET_CHARA, SET_MOTION, SET_PLAYDATA, EFFECT, FADEIN_FIELD, EFFECT_OFF, SET_CAMERA,
        DATA_CAMERA, CHANGE_FIELD, HIDE_FIELD, MOVE_FIELD, FADEOUT_FIELD, EYE_ANIM, MOUTH_ANIM, HAND_ANIM, LOOK_ANIM, EXPRESSION, LOOK_CAMERA,
        LYRIC, MUSIC_PLAY, MODE_SELECT, SHADOWHEIGHT, EDIT_FACE, MOVE_CAMERA, SHADOWPOS, EDIT_LYRIC, EDIT_TARGET, EDIT_MOUTH, EDIT_MOVE, EDIT_SHADOW,
        EDIT_EYELID, EDIT_EYE, EDIT_ITEM, EDIT_EFFECT, EDIT_DISP, EDIT_HAND_ANIM, AIM, HAND_ITEM, EDIT_BLUSH, NEAR_CLIP, CLOTH_WET, LIGHT_ROT,
        SCENE_FADE, TONE_TRANS, SATURATE, FADE_MODE, AUTO_BLINK, PARTS_DISP, CHARA_SIZE, CHARA_HEIGHT_ADJUST, ITEM_ANIM, CHARA_POS_ADJUST, SCENE_ROT,
        PV_BRANCH_MODE, DATA_CAMERA_START, MOVIE_PLAY, MOVIE_DISP, WIND, OSAGE_STEP, OSAGE_MV_CCL, CHARA_COLOR, SE_EFFECT, EDIT_MOVE_XYZ, EDIT_EYELID_ANIM,
        EDIT_INSTRUMENT_ITEM, EDIT_MOT_SMOOTH_LEN, EDIT_MOTION, EDIT_MOTION_LOOP, EDIT_EXPRESSION, EDIT_EYE_ANIM, EDIT_MOUTH_ANIM, EDIT_CAMERA,
        EDIT_MODE_SELECT, PV_END_FADEOUT, RESERVE, PV_AUTH_LIGHT_PRIORITY, PV_CHARA_LIGHT, PV_STAGE_LIGHT, TARGET_EFFECT, FOG, BLOOM, COLOR_CORRECTION,
        DOF, CHARA_ALPHA, AUTO_CAPTURE_BEGIN, MANUAL_CAPTURE, TOON_EDGE, SHIMMER, ITEM_ALPHA, MOVIE_CUT, CROSSFADE, SUBFRAMERENDER, EVENT_JUDGE,
        TOON__EDGE, FOG_ENABLE, EDIT_CAMERA_BOX, EDIT_STAGE_PARAM, EDIT_CHANGE_FIELD, DUMMY, CHARA_SHADOW_QUALITY, STAGE_SHADOW_QUALITY, COMMON_LIGHT,
        TONE_MAP, IBL_COLOR, REFLECTION, CHROMATIC_ABERRATION, STAGE_SHADOW, REFLECTION_QUALITY, CREDIT_TITLE, BAR_POINT, BEAT_POINT, MIKUDAYO_ADJUST,
        LYRIC_2, LYRIC_READ, LYRIC_READ_2, ANNOTATION, STAGE_EFFECT, BAR_TIME_SET, TARGET_FLYING_TIME, TARGET_FLAG, TARGET, SONG_EFFECT, SONG_EFFECT_ATTACH,
        LIGHT_AUTH, FADE, SET_STAGE_EFFECT_ENV, COMMON_EFFECT_AET_FRONT, COMMON_EFFECT_AET_FRONT_LOW, COMMON_EFFECT_PARTICLE, SONG_EFFECT_ALPHA_SORT,
        LOOK_CAMERA_FACE_LIMIT, ITEM_LIGHT, CHARA_EFFECT, MARKER, CHARA_EFFECT_CHARA_LIGHT, ENABLE_COMMON_LIGHT_TO_CHARA, ENABLE_FXAA, ENABLE_TEMPORAL_AA,
        ENABLE_REFLECTION, BANK_BRANCH, BANK_END, VR_LIVE_MOVIE, VR_CHEER, VR_CHARA_PSMOVE, VR_MOVE_PATH, VR_SET_BASE, VR_TECH_DEMO_EFFECT, VR_TRANSFORM,
        GAZE, TECH_DEMO_GESUTRE, VR_CHEMICAL_LIGHT_COLOR, VR_LIVE_MOB, VR_LIVE_HAIR_OSAGE, VR_LIVE_LOOK_CAMERA, VR_LIVE_CHEER, VR_LIVE_GESTURE, VR_LIVE_CLONE,
        VR_LOOP_EFFECT, VR_LIVE_ONESHOT_EFFECT, VR_LIVE_PRESENT, VR_LIVE_TRANSFORM, VR_LIVE_FLY, VR_LIVE_CHARA_VOICE, UNKNOWN_COMMAND, MOT_SMOOTH, ITEM_ANIM_ATTACH,
        SHADOW_RANGE, HAND_SCALE, LIGHT_POS, FACE_TYPE, SHADOW_CAST, EDIT_MOTION_F, COLOR_COLLE, AOTO_CAP, MAN_CAP, TOON, MOVIE_CUT_CHG, CHARA_LIGHT, STAGE_LIGHT,
        AGEAGE_CTRL, PSE, PV_END, END,
    }
}